﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Reflection;

namespace RpcGenerator
{
    enum NamespaceType
    {
        CSharp,
        AS3,
        Cpp
    }

    class MessageNamespace
    {
        public string Namespace { get; set; }
        public List<string> ReferenceNamespace { get; set; }

        public MessageNamespace()
        {
            ReferenceNamespace = new List<string>() { "System", "System.Collections.Generic","MessageSystem.Rpc","MessageSystem.Managed"};
        }


    }

    class MethodDescription
    {
        public Type Interface { get; set; }
        public MethodInfo Method { get; set; }
    }

    enum MessageFieldType
    {
        PrimitiveType,
        GenericType,
        ClientType,
    }

    class MemberDescription
    {
        public Type Type { get; set; }
        public string Name { get; set; }
        public string GenericTypeName { get; set; }
        public int ObjectIndex { get; set; }

        public MessageFieldType GetMessageFieldType()
        {
            return GetMessageFieldType(Type);
        }

        public static MessageFieldType GetMessageFieldType(System.Type Type)
        {
            if (IsPrimitiveType(Type))
                return MessageFieldType.PrimitiveType;
            if (IsGenericType(Type))
                return MessageFieldType.GenericType;
            return MessageFieldType.ClientType;
        }

        public bool IsPrimitiveType()
        {
            return IsPrimitiveType(Type);
        }

        public bool IsEnum()
        {
            return Type.IsEnum;
        }

        public bool IsGenericType()
        {
            return IsGenericType(Type);
        }

        public bool IsDateTimeType()
        {
            return IsDateTimeType(Type);
        }

        public bool IsString()
        {
            return IsString(Type);
        }

        public static bool IsString(System.Type Type)
        {
            return typeof(string) == Type;
        }

        public static bool IsGenericType(Type tp)
        {
            return tp.IsGenericType;
        }

        public static bool IsPrimitiveType(Type tp)
        {
            return primitiveTypes.Contains(tp) || tp.IsEnum;
        }

        public static bool IsDateTimeType(Type tp)
        {
            return typeof(DateTime) == tp;
        }

        public static Type GetGenericType(Type tp)
        {
            return tp.GetGenericArguments()[0];
        }

        public Type GetGenericType()
        {
            return GetGenericType(Type);
        }

        private static Type[] primitiveTypes = { typeof(sbyte), typeof(byte), typeof(Int16),typeof(UInt16),
                                                 typeof(Int32),typeof(UInt32),typeof(Int64),typeof(UInt64),
                                                 typeof(float),typeof(double),typeof(bool) ,typeof(DateTime),
                                                 typeof(string)
                                               };


    }

    class MessageFieldMemberDescription:MemberDescription
    {
 
    }

    class MessageFieldDescription:MemberDescription
    {
        public int ObjectCount { get; set; }
        public int MemberMaskSize { get; set; }
        public List<MessageFieldMemberDescription> Members { get; set; }
    }

    class MessageDescription
    {
        public List<MessageFieldDescription> Fields { get; set; }
        public Int32 MessageId { get; set; }
        public Int16 MethodId { get; set; }
        public string Name { get; set; }
        public Type Type { get; set; }
        public bool IsRequest { get; set; }
        public MethodDescription Method { get; set; }
        public MessageDescription Response { get; set; }
        public bool SupportBroadcast { get; set; }
        public bool NeedEncrypt { get; set; }
        public bool AsynMethod { get; set; }
        public int ObjectCount { get; set; }
        public int ObjectMaskSize { get; set; }
        public List<MessageFieldDescription> SharedObjects { get; set; }
    }
}
